/*
* @(#)ListDmsPublicDocumentAction.java
*
* Copyright (c) 2003 DCIVision Ltd
* All rights reserved.
*
* This software is the confidential and proprietary information of DCIVision
* Ltd ("Confidential Information").  You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with DCIVision Ltd.
*/

package com.dcivision.dms.web;

import java.io.File;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.dms.DmsErrorConstant;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsRoot;
import com.dcivision.dms.bean.DmsValidation;
import com.dcivision.dms.bean.MtmDocumentRelationship;
import com.dcivision.dms.core.DmsTreeController;
import com.dcivision.dms.core.DocumentOperationManager;
import com.dcivision.dms.core.DocumentRetrievalManager;
import com.dcivision.dms.core.DocumentValidateManager;
import com.dcivision.dms.core.RootOperationManager;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.dms.dao.DmsRootDAObject;
import com.dcivision.dms.dao.MtmDocumentRelationshipDAObject;
import com.dcivision.framework.ApplicationContainer;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.dao.SysUserDefinedIndexDAObject;
import com.dcivision.framework.taglib.layout.PagePathTag;
import com.dcivision.framework.taglib.layout.PageTitleTag;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;
import com.dcivision.workflow.bean.MtmWorkflowProgressSystemObject;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.dao.MtmWorkflowProgressSystemObjectDAObject;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;


/**
 * <p>Class Name:       ListDmsPublicDocumentAction.java    </p>
 * <p>Description:      The list action class for ListUserRecord.jsp</p>
 * @author              Zoe Shum
 * @company             DCIVision Limited
 * @creation date       01/08/2003
 * @version             $Revision: 1.61.2.11 $
 */
public class ListDmsPublicDocumentAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.61.2.11 $";


  /**
   *  Constructor - Creates a new instance of ListDmsPublicDocumentAction and define the default listName.
   */
  public ListDmsPublicDocumentAction() {
    super();
    this.setListName("dmsPublicDocumentList");
  }

  /**
   * getMajorDAOClassName
   *
   * @return  The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return("com.dcivision.dms.dao.DmsDocumentDAObject");
  }

  /**
   * getFunctionCode
   *
   * @return  The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return(SystemFunctionConstant.DMS_PUBLIC_FOLDER);
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
    if(!Utility.isEmpty(request.getSession().getAttribute(org.apache.struts.Globals.MESSAGE_KEY))){
      this.addMessage(request, (String)request.getSession().getAttribute(org.apache.struts.Globals.MESSAGE_KEY));
      request.getSession().removeAttribute(org.apache.struts.Globals.MESSAGE_KEY);
    }
    if(!Utility.isEmpty(request.getSession().getAttribute(org.apache.struts.Globals.ERROR_KEY))){
      this.addError(request, (String)request.getSession().getAttribute(org.apache.struts.Globals.ERROR_KEY));
      request.getSession().removeAttribute(org.apache.struts.Globals.ERROR_KEY);
    }
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);

    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    docRetrievalManager.checkNSetDefaultProfileList(request);

    AbstractSearchForm searchForm = (AbstractSearchForm) form;
    if(request.getAttribute("Return") !=null && !request.getAttribute("Return").equals("Y")){
      searchForm = findExpectForm4ListAction(mapping, (AbstractSearchForm) form, request);
    }
      log.info(this.getClass().getName()+", OP Mode:"+searchForm.getOpMode()+", Nav Mode:"+searchForm.getNavMode());

      // Set the function code for current action.
      ActionForward forward = this.retrieveFunctionCode(request, response, mapping);
      if (forward!=null) {
        return forward;
      }

      if (GlobalConstant.OP_MODE_LIST_DELETE.equals(searchForm.getOpMode())) {
        try {
          this.deleteListData(mapping, searchForm, request, response);
          this.commit(request);
          //'cas have customer messages,cancel this message
          searchForm.setBasicSelectedID(null);
          searchForm.setOpMode(null);

          // Check for all item deletes per page
          this.getListData(mapping, searchForm, request, response);
        } catch (ApplicationException e) {
          this.rollback(request);
          this.handleApplicationException(request, e);
          request.setAttribute(this.m_sListName, new ArrayList());

          try {
            this.getListData(mapping, searchForm, request, response);
            searchForm.setOpMode("");
          } catch (ApplicationException e1) {
            this.handleApplicationException(request, e1);
            request.setAttribute(this.m_sListName, new ArrayList());
          }
        }
      } else {
        try {
          this.getListData(mapping, searchForm, request, response);
        } catch (ApplicationException e) {
          this.handleApplicationException(request, e);
          request.setAttribute(this.m_sListName, new ArrayList());
          if ("errors.dms.have_no_function_permission".equals(e.getMsgCode()) || "errors.framework.file_is_deleted".equals(e.getMsgCode())) {
            request.setAttribute("no_permission","true");
          }
        }
      }

      List resultList = (List)request.getAttribute(this.m_sListName);
      while ( (resultList.size()==0) && (TextUtility.parseInteger(searchForm.getCurStartRowNo())>TextUtility.parseInteger(searchForm.getPageOffset())) ) {
        int prvRowNo = TextUtility.parseInteger(searchForm.getCurStartRowNo())-TextUtility.parseInteger(searchForm.getPageOffset());
        searchForm.setCurStartRowNo(TextUtility.formatInteger(prvRowNo));
        this.getListData(mapping, searchForm, request, response);
      }

      return mapping.findForward(GlobalConstant.NAV_MODE_LIST);


  }
  /**
   * getListData
   *
   * Override the parent's function. Purpose in create the default personal folder when non-exists,
   * and load the dmsDocument list.
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void getListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    ListDmsPublicDocumentForm docSearchForm = (ListDmsPublicDocumentForm) form;
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    RootOperationManager rootOperationManager = new RootOperationManager(sessionContainer, conn);
    DmsTreeController controller = new DmsTreeController(sessionContainer, conn);
    DmsDocument documentRoot = null;
    DmsRoot nDmsRoot = null;
    try {
      // Retieve the root folder document object.
      documentRoot = docRetrievalManager.getRootFolderByRootID(TextUtility.parseIntegerObj(docSearchForm.getRootID()));
      request.setAttribute("rootFolder", documentRoot);
      if(docSearchForm.getRootID()==null){
        String rootID = (String)request.getAttribute("rootID");
        String parentID = (String)request.getAttribute("parentID");
        docSearchForm.setRootID(rootID);
        docSearchForm.setParentID(parentID);
      }

      if( docSearchForm.getRootID() != null ) {
        nDmsRoot= docRetrievalManager.getDmsRoot(TextUtility.parseIntegerObj(docSearchForm.getRootID()));
        controller.initPermissionOnlyByParameters(nDmsRoot.getRootType(), TextUtility.parseIntegerObj(docSearchForm.getRootID()), nDmsRoot.getOwnerID(), TextUtility.parseIntegerObj(docSearchForm.getParentID()));
      }
      // Retrieve the location path of the folder.
      Integer parentID = TextUtility.parseIntegerObj(docSearchForm.getParentID());
      
      String path = docRetrievalManager.getLocationPath(parentID);
      request.setAttribute("location", path);

      // Retrieve the accessible public root list.
      DmsRootDAObject dmsRootDAO = new DmsRootDAObject(sessionContainer, conn);
      List publicRootList = dmsRootDAO.getPublicRootList();
      request.setAttribute("publicRootList", publicRootList);
      DocumentValidateManager docValidateManager = new DocumentValidateManager(sessionContainer, conn);
      
      // check parent folder exist
      if(!docValidateManager.isParentHasDelete(parentID)){
        request.setAttribute("location", null);
        request.setAttribute("publicRootList", null);
        request.setAttribute("parentID", null);
        request.setAttribute("rootID", null);
        request.setAttribute("rootFolder", null);
        request.setAttribute(this.m_sListName, null);
        throw new ApplicationException("errors.framework.file_is_deleted");
      }
      // check any document profile of the system
      SysUserDefinedIndexDAObject sysUserDefinedIndexDAO = new SysUserDefinedIndexDAObject(sessionContainer, conn);
      List sysUDFList = sysUserDefinedIndexDAO.getListByStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
      request.setAttribute("sysUDFList",sysUDFList);

      // check permission
      boolean havePermission = docValidateManager.checkHasPermissionOnObject(GlobalConstant.OBJECT_TYPE_DOCUMENT,
          TextUtility.parseIntegerObj(docSearchForm.getParentID()), TextUtility.parseIntegerObj(docSearchForm.getRootID()), "R");
      if (havePermission) {
        // Call the super list function.
        if (!SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.DMS_DISPLALY_NO_ACCESS_DOCUUMENT)){
          this.getAccessListData(docSearchForm,request);
        } else {
          super.getListData(mapping, docSearchForm, request, response);
        }

        // Retrive the workflow relationship.
        List listDoc = (List)request.getAttribute(this.m_sListName);
        List listWorkflowRelation = new ArrayList();
        MtmWorkflowProgressSystemObjectDAObject mtmWfProgressSysObjDAO = new MtmWorkflowProgressSystemObjectDAObject(this.getSessionContainer(request), conn);
        WorkflowRecordDAObject workflowRecordDAO = new WorkflowRecordDAObject(this.getSessionContainer(request), conn);
        for (int i = 0; i < listDoc.size(); i++) {
          List tmpList =new ArrayList();
          try {
            if(DmsDocument.DOCUMENT_LINK.equals(((DmsDocument)listDoc.get(i)).getDocumentType())){
              if(!Utility.isEmpty(((DmsDocument)listDoc.get(i)).getID())){
                DmsDocument targetDoc = docRetrievalManager.getRelationshipTargetDocument(((DmsDocument)listDoc.get(i)).getID(),((DmsDocument)listDoc.get(i)).getDocumentType());
                if(targetDoc!=null){
                  tmpList = mtmWfProgressSysObjDAO.getListByBeanClassNameObjectID(listDoc.get(i).getClass().getName(), targetDoc.getID());
                }
              }
            }else{
              tmpList = mtmWfProgressSysObjDAO.getListByBeanClassNameObjectID(listDoc.get(i).getClass().getName(), ( (DmsDocument)listDoc.get(i)).getID());
            }
          }catch (Exception ex) {
            log.warn("Database have dirty reocrds, "+ex, ex);
          }

          List tmpRow = new ArrayList();
          listWorkflowRelation.add(i, tmpRow);
          for (int j = 0; j < tmpList.size(); j++) {
            MtmWorkflowProgressSystemObject tmpObj = (MtmWorkflowProgressSystemObject)tmpList.get(j);
            WorkflowRecord wfRec=null;
            try{
              wfRec = (WorkflowRecord)workflowRecordDAO.getObjectByTrackID(tmpObj.getTrackID());
            }catch(ApplicationException appx){
              if(!ErrorConstant.DB_RECORD_NOT_FOUND_ERROR.equals(appx.getMsgCode())){
                throw appx;
              }
            }
            if (wfRec != null) {
              tmpRow.add(new Object[] {wfRec, tmpObj.getTrackID()});
            }
          }
        }
        request.setAttribute("workflowRelationshipList", listWorkflowRelation);
        mtmWfProgressSysObjDAO=null;
        workflowRecordDAO=null;
      } else {
        request.setAttribute(this.m_sListName, new ArrayList());
        request.setAttribute("workflowRelationshipList", new ArrayList());
      }
      this.commit(request);
      sessionContainer=null;
      docRetrievalManager.release();
      rootOperationManager.release();
      docValidateManager.release();
    } catch (ApplicationException appEx) {
      log.error(appEx, appEx);
      this.rollback(request);
      throw appEx;
    } catch (Exception e) {
      log.error(e, e);
      this.rollback(request);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
      conn=null;
    }
  }

  /**
   *  Method deleteListData() - delete the item(s) from listing page
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     void
   *  @throws     ApplicationException  Throws ApplicationException the deleteion failed
   *  @deprecated This method has deprecated
   */
  public void deleteListData2(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    MtmDocumentRelationshipDAObject dmsMtmDocumentRelationshipDAO = new MtmDocumentRelationshipDAObject (sessionContainer, conn);
    DocumentOperationManager docOperationManager = null;
    DocumentRetrievalManager docRetrievalManager = null;
    List relationshipList=new ArrayList();
    List indirectRelationDocumentList=new ArrayList();
    ArrayList clipboardList = (ArrayList)request.getSession().getAttribute("DMS_CLIPBOARD");
    boolean isLightVersion = sessionContainer.getAppContainer().isLightVersion();


    try {
      docOperationManager = new DocumentOperationManager(sessionContainer, conn);
      docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);

      DmsDocumentDAObject dmsDocmentDAO = new DmsDocumentDAObject(sessionContainer, conn);
      DmsDocument targetDoc = null;
      String itstatus = "";

      String[] selectedID = form.getBasicSelectedID();
      for (int i = 0; i < selectedID.length; i++) {
        targetDoc = (DmsDocument)dmsDocmentDAO.getObjectByID(TextUtility.parseIntegerObj(selectedID[i]));
        itstatus = targetDoc.getItemStatus();
        if (!Utility.isEmpty(selectedID[i])) {
          DmsDocument document = docRetrievalManager.getDocument(TextUtility.parseIntegerObj(selectedID[i]));
          if (DmsDocument.FOLDER_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())) {
            if ("X".equals(itstatus)) {
              throw new ApplicationException(ErrorConstant.DMS_MESSAGE_CHECKOUT_NOT_DELETE);
            }else{
              //docOperationManager.deleteFolder(document);
                List notDeleteDocumentList = docOperationManager.deleteFolderExpectSpecDocument(document);
                if(notDeleteDocumentList !=null &&notDeleteDocumentList.size() != 0 ){
                    for(int j = 0 ; j < notDeleteDocumentList.size() ;j++){
                      List tempList = (List)notDeleteDocumentList.get(j);
                      DmsDocument tmpDocument = (DmsDocument)tempList.get(0);
                      String tempDeleteType =  (String)tempList.get(1);
                      //delete successfull
                      if("S".equals( tempDeleteType)){
                        this.addMessage(request,DmsErrorConstant.MESSAGE_RECORD_DELETED_SUCCESS,docRetrievalManager.getLocationPath(tmpDocument.getID()));
                      }
                    }

                    for(int j = 0 ; j < notDeleteDocumentList.size() ;j++){
                      List tempList = (List)notDeleteDocumentList.get(j);
                      DmsDocument tmpDocument = (DmsDocument)tempList.get(0);
                      String tempDeleteType =  (String)tempList.get(1);
                      // checkout document not allow delete
                      if("C".equals( tempDeleteType)){
                        this.addMessage(request,DmsErrorConstant.MESSAGE_RECORD_CHECKOUT_NOTDELETED,docRetrievalManager.getLocationPath(tmpDocument.getID()));
                      }
                    }

                    for(int j = 0 ; j < notDeleteDocumentList.size() ;j++){
                      List tempList = (List)notDeleteDocumentList.get(j);
                      DmsDocument tmpDocument = (DmsDocument)tempList.get(0);
                      String tempDeleteType =  (String)tempList.get(1);
                      // not delete permission not allow delete
                      if("P".equals( tempDeleteType)){
                        this.addMessage(request,DmsErrorConstant.MESSAGE_RECORD_NOTPERMISSION_NOTDELETED,docRetrievalManager.getLocationPath(tmpDocument.getID()));
                      }
                    }
                }
            }
          } else {
            if ("X".equals(itstatus)) {
                throw new ApplicationException(ErrorConstant.DMS_MESSAGE_CHECKOUT_NOT_DELETE);
            }else{
              relationshipList=dmsMtmDocumentRelationshipDAO.getListByRelationIDRelationType(document.getID(),null);
              indirectRelationDocumentList=dmsMtmDocumentRelationshipDAO.getListByIDRelationType(document.getID(),null);
              if(relationshipList.size()>0){
                for(int n=0;n<relationshipList.size();n++){
                  MtmDocumentRelationship relationshipObj = (MtmDocumentRelationship)relationshipList.get(n);
                  relationshipObj.setRecordStatus(GlobalConstant.RECORD_STATUS_INACTIVE);
                  dmsMtmDocumentRelationshipDAO.updateObject(relationshipObj);
                }
              }
              if(indirectRelationDocumentList.size()>0){
                for(int n=0;n<indirectRelationDocumentList.size();n++){
                  MtmDocumentRelationship relationshipObj =(MtmDocumentRelationship)indirectRelationDocumentList.get(n);
                  relationshipObj.setRecordStatus(GlobalConstant.RECORD_STATUS_INACTIVE);
                  dmsMtmDocumentRelationshipDAO.updateObject(relationshipObj);
                 }
              }
                docOperationManager.deleteDocument(document);
            }
          }

          /** Lite version - No clipboard operation */
          if(!isLightVersion){
            if(clipboardList.contains(new Integer(selectedID[i]))){
              clipboardList.remove(new Integer(selectedID[i]));
            }
          }
        }
      }
      addMessage(request, MESSAGE_RECORDS_DELETED, ""+form.getBasicSelectedID().length);
    } catch (ApplicationException appEx) {
      throw appEx;
    } catch (Exception e) {
      log.error("Error in deletion", e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }finally {
        conn = null;
        sessionContainer = null;
        docOperationManager.release();
        docRetrievalManager.release();
        docOperationManager = null;
        docRetrievalManager = null;
    }
  }

  public void deleteListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {

    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentValidateManager docValidateManager = new DocumentValidateManager(sessionContainer, conn);
    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    DmsDocumentDAObject dmsDocumentDAO = new DmsDocumentDAObject(sessionContainer, conn);
    ApplicationContainer container = (ApplicationContainer)request.getSession().getServletContext().getAttribute(GlobalConstant.APPLICATION_CONTAINER_KEY);

    String[] selectedID = form.getBasicSelectedID();
    selectedID = docValidateManager.validatorFilterDocID(selectedID);

    boolean isIgnoreDeleteShortcut = ((ListDmsDocumentForm)form).isIgnoreDeleteShortcut();

    //step 1: loop and validate tree node, add id to lstIdHasRight/lstIdMisRight/lstIdBeLocked
    for (int n=0; n<selectedID.length; n++) {
      Integer srcDocumentId = TextUtility.parseIntegerObj(selectedID[n]);
      DmsDocument sourceDocument = (DmsDocument)dmsDocumentDAO.getObjectByID(srcDocumentId);
      DmsValidation validation = docValidateManager.validateDeleteAction(sourceDocument, isIgnoreDeleteShortcut);

      //step 2: begin delete documents
      String cacheKey = "D"+sessionContainer.getSessionID()+""+System.currentTimeMillis();
      try {
        List deleteDocumentIds = validation.getLstIdAccept();
        //step 2.1: check and lock operation id to application cache
        boolean success = container.checkAndLockDocumentOperationID(cacheKey, deleteDocumentIds, "ACDIMU");
        if (!success) {
          this.addError(request, "errors.dms.fail_to_delete", docRetrievalManager.getLocationPath(srcDocumentId));
          this.addError(request, "errors.dms.cannot_edit_now");
        }else {
//        step 2.2: delete documents
          docOperationManager.deleteDocument(sourceDocument, validation);

          //step 2.3: message throws
          List lstIdHasRight = validation.getLstIdAccept();
          List lstIdMisRight = validation.getLstIdReject();
          List lstIdBeLocked = validation.getLstIdlocked();
          List lstIdBeDeleted = validation.getLstIdDeleted();
          List lstIdBeArchived = validation.getLstIdArchived();
          List lstIdRelatedShortcut = validation.getLstIdHaveRelationship();
          String locationPath = docRetrievalManager.getLocationPath(srcDocumentId);
          if (validation.isSuccess()) {
            this.addMessage(request, "dms.message.document_deleted_success", locationPath, String.valueOf(lstIdHasRight.size()));
          }else {
            this.addError(request, "errors.dms.fail_to_delete", locationPath);
            for (int i=0; i<lstIdMisRight.size(); i++) {
              this.addError(request,"errors.dms.no_permission",docRetrievalManager.getLocationPath((Integer)lstIdMisRight.get(i)));
            }
            for (int i=0; i<lstIdBeLocked.size(); i++) {
              this.addError(request,"errors.dms.been_checkout",docRetrievalManager.getLocationPath((Integer)lstIdBeLocked.get(i)));
            }
            for (int i=0; i<lstIdBeDeleted.size(); i++) {
              this.addError(request,"errors.dms.been_deleted",docRetrievalManager.getLocationPath((Integer)lstIdBeDeleted.get(i)));
            }
            for (int i=0; i<lstIdBeArchived.size(); i++) {
              this.addError(request,"errors.dms.been_archived",docRetrievalManager.getLocationPath((Integer)lstIdBeArchived.get(i)));
            }
            for (int i=0; i<lstIdRelatedShortcut.size(); i++) {
              this.addError(request,"errors.dms.has_relationship",docRetrievalManager.getLocationPath((Integer)lstIdRelatedShortcut.get(i)));
            }
            if (!Utility.isEmpty(lstIdHasRight)) {
              this.addError(request, "dms.message.document_been_deleted",String.valueOf(lstIdHasRight.size()));
            }
          }

          //step 2.4: delete from clipboard if it present
          List clipboardList = (List)request.getSession().getAttribute("DMS_CLIPBOARD");
          if (clipboardList!=null && !clipboardList.isEmpty()) {
            for (int i=0; i<clipboardList.size(); i++) {
              if(deleteDocumentIds.contains(clipboardList.get(i))) {
                clipboardList.remove(i--);
              }
            }
          }
        }
      }catch (ApplicationException ex) {
        throw ex;
      }catch (Exception ex) {
        throw new ApplicationException(ex);
      }finally {
        container.unlockDmsDocumentOperationID(cacheKey);
      }
    }
    conn = null;
    sessionContainer = null;
    container = null;
    docValidateManager.release();
    docOperationManager.release();
    docRetrievalManager.release();
  }

  public List getDocList(AbstractSearchForm form, HttpServletRequest request) throws ApplicationException {
    List docList = new ArrayList();
    ListDmsPublicDocumentForm docForm = (ListDmsPublicDocumentForm)form;
    Connection conn = this.getConnection(request);
    SessionContainer sessionContainer = this.getSessionContainer(request);
    PermissionManager pm = sessionContainer.getPermissionManager();

    DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
    DmsDocumentDAObject documentDAO = new DmsDocumentDAObject(sessionContainer,conn);
    DmsRootDAObject dmsRootDAO = new DmsRootDAObject(sessionContainer,conn);
    List tmpDocList = documentDAO.getFullList(docForm);

    if (tmpDocList != null){
       for (int i=0;tmpDocList.size()>i;i++){
        DmsDocument dmsDoc = (DmsDocument)tmpDocList.get(i);

        if (DmsDocument.DOCUMENT_LINK.equals(dmsDoc.getDocumentType())){
          DmsDocument tmpDoc = docRetrieval.getRelationshipTargetDocument(dmsDoc.getID(),DmsDocument.DOCUMENT_LINK);
          if (tmpDoc == null) {
            continue;
          }
          DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(tmpDoc.getRootID());

          if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,tmpDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
            docList.add(dmsDoc);
          }
        } else {
          DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(dmsDoc.getRootID());
          if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,dmsDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
            docList.add(dmsDoc);
          }
        }
      }
    }

    return docList;
  }

  public List getPageList(AbstractSearchForm form, HttpServletRequest request) throws ApplicationException {
    ListDmsPublicDocumentForm docForm = (ListDmsPublicDocumentForm)form;
    List result = new ArrayList();
    int pageSize = TextUtility.parseInteger(docForm.getPageOffset());

    while (result.size() < pageSize){
      List tmpList = this.getDocList(docForm,request);
      if (tmpList == null || tmpList.size() < 1) {
        break;
      }
      for (int k = 0; tmpList.size() > k; k++){
        if (result.size() >= pageSize) {
          break;
        }
        result.add(tmpList.get(k));
    }
      docForm.setCurStartRowNo(TextUtility.parseInteger(docForm.getCurStartRowNo()) + pageSize + "");
    }
    return result;
  }

  public String getCurPageCursor(String cursor,int CurPageNo){
    String curCursor = "1";
    if (Utility.isEmpty(cursor)) {
      return curCursor;
    }
    StringTokenizer cursorToken = new StringTokenizer(cursor,";");

    while (cursorToken.hasMoreTokens()){
      String tmpCursor = cursorToken.nextToken();
      if (tmpCursor.indexOf(CurPageNo + "-") != -1){
        StringTokenizer tmpToken = new StringTokenizer(tmpCursor,"-");
        tmpToken.nextToken();
        curCursor  = tmpToken.nextToken();
      }
    }
    return curCursor;
  }

  public List getAccessListData(AbstractSearchForm form, HttpServletRequest request) throws ApplicationException {
    ListDmsPublicDocumentForm docSearchForm = (ListDmsPublicDocumentForm)form;
    Integer pageAmountInc = SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.DMS_LIST_PAGEAMOUNT);
    List result = new ArrayList();
    int pageSize = TextUtility.parseInteger(docSearchForm.getPageOffset());
    int curPageNo = TextUtility.parseInteger(docSearchForm.getCurPageNO());
    int lastPageNo = TextUtility.parseInteger(docSearchForm.getLastPageNO());
    int pageAmount = TextUtility.parseInteger(docSearchForm.getPageAmount());

    StringBuffer cursor = null;
    if (docSearchForm.getCursor() != null){
      cursor = new StringBuffer(docSearchForm.getCursor());
    } else {
      cursor = new StringBuffer();
    }

    if (curPageNo == 0 || curPageNo == 1){
      curPageNo = 0;
      cursor.delete(0,cursor.length());
    }

    //get list Date
    String startRowNo = this.getCurPageCursor(cursor.toString(),curPageNo);
    docSearchForm.setCurStartRowNo(startRowNo);
    result = this.getPageList(docSearchForm,request);

    //get cursor
    List cursorList = new ArrayList();
    DmsDocument tmpDoc = null;

    if (curPageNo == lastPageNo || curPageNo == 0){
      //page = 1
      if (!(result.size() < pageSize)){
        //set start page cursor
        tmpDoc = (DmsDocument)result.get(pageSize-1);
        if (tmpDoc != null){
          docSearchForm.setCurStartRowNo(tmpDoc.getRowNum()+1 + "");
        }

        int loopTimes = 0;
        if (curPageNo == 0){
          loopTimes = 1;
          lastPageNo = 1;
        }

        for (;loopTimes<pageAmountInc.intValue(); loopTimes++){
          cursorList = this.getPageList(docSearchForm,request);

          if (!Utility.isEmpty(cursorList)){
            tmpDoc = (DmsDocument)cursorList.get(0);
            ++lastPageNo;
            pageAmount = lastPageNo;
            cursor.append(lastPageNo);
            cursor.append("-");
            cursor.append(tmpDoc.getRowNum());
            cursor.append(";");

            if (!(cursorList.size() < pageSize)){
              tmpDoc = (DmsDocument)cursorList.get(pageSize-1);
              if (tmpDoc == null) {
                break;
              }
              docSearchForm.setCurStartRowNo(tmpDoc.getRowNum()+1 + "");
            } else {
              lastPageNo = -1;
              break;
            }

          } else {
            lastPageNo = -1;
          }
        }

        if (lastPageNo != -1 && lastPageNo == curPageNo + pageAmountInc.intValue()){
          cursorList = this.getPageList(docSearchForm,request);
          if (Utility.isEmpty(cursorList)) {
            lastPageNo = -1;
          }
        }

      }
    }

    if (curPageNo == 0) {
      curPageNo = 1;
    }
    docSearchForm.setCursor(cursor.toString());
    docSearchForm.setPageAmount(pageAmount + "");
    docSearchForm.setCurPageNO(curPageNo + "");
    docSearchForm.setLastPageNO(lastPageNo + "");
    docSearchForm.setPageAmount(pageAmount + "");
    request.setAttribute(this.m_sListName,result);
    return result;
  }
  
  public void setPageTitle(HttpServletRequest request, HttpServletResponse response, ActionForm form, ActionMapping mapping,
      ActionForward actionForward) throws NumberFormatException, ApplicationException {
    super.setPageTitle(request, response, form, mapping, actionForward);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(getSessionContainer(request), getConnection(request));
    ListDmsDocumentForm listForm = (ListDmsDocumentForm) form;
    Integer folderID = Integer.valueOf(listForm.getParentID());
    DmsDocument currentFolder = docRetrievalManager.getDocument(folderID);
    
    final String pathSeparator = " " + File.separator + " ";
    
    // Phase 1 : Generate header page title.
    request.setAttribute(PageTitleTag.HEADER_FOLDER_NAME_KEY, currentFolder.getDocumentName());
    
    // Phase 2 : Generate folder location path.
    int pathDisplayNum = SystemParameterFactory.getSystemParameter(SystemParameterConstant.LOCATION_DISPLAY_NUMBER) != null ? Integer.parseInt(SystemParameterFactory.getSystemParameter(SystemParameterConstant.LOCATION_DISPLAY_NUMBER)) : SystemParameterConstant.DEFAULT_LOCATION_DISPLAY_NUMBER;
    Integer parentFolderID = currentFolder.getParentID();
    int pathCount = 0;
    StringBuffer locationBuffer = new StringBuffer();
    StringBuffer ellipsisBuffer = new StringBuffer();
    StringBuffer rootFolderPathBuffer = new StringBuffer();

    while (parentFolderID.intValue() > 0) {
      pathCount++;
      
      StringBuffer buffer = new StringBuffer();
      DmsDocument document = docRetrievalManager.getDocument(parentFolderID);
      boolean isRootFolder = document.getParentID().intValue() == 0 ? true : false;
      boolean havePermission2Read = getSessionContainer(request).getPermissionManager().hasAccessRight(GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID(),PermissionManager.READ_PERMISSION);

      buffer.append(pathSeparator);
      if (havePermission2Read) {
        buffer.append(
            "<a href=\"" +
                  request.getContextPath() + "/dms/ListDmsPublicDocument.do?" +
                  "rootID=" + document.getRootID() +
                  "&parentID=" + document.getID() +
                  "&curFunctionCode=" + SystemFunctionConstant.DMS_PUBLIC_FOLDER + "&myPage=ListDmsPublicDocument" +
                  "\"" +
            ">"
            );
      }
      buffer.append(document.getDocumentName());
      if (havePermission2Read) {
        buffer.append("</a>");
      }
      
      if (isRootFolder) {
        rootFolderPathBuffer.insert(0, buffer);
      } else if ((pathDisplayNum > 0) && (pathCount > pathDisplayNum)) {
        ellipsisBuffer.insert(0, buffer);
      } else {
        locationBuffer.insert(0, buffer);
      }
      
      parentFolderID = document.getParentID();
    }
    
    if (!Utility.isEmpty(ellipsisBuffer)) {
      String ellipsisStr = ellipsisBuffer.toString();
      if (ellipsisStr.startsWith(pathSeparator)) {
        ellipsisStr = ellipsisStr.substring((pathSeparator).length());
      }
      
      locationBuffer.insert(0,
          pathSeparator +
          "<span id=\"ellipsisSection\">" +
          "<a " +
            "href=\"#\" " +
            "onmouseover=\"return getDocumentInfo('"
              + TextUtility.escapeJSString(ellipsisStr) +
              "')\" " +
            "onmouseout=\"return nd()\" " +
            "onclick=\"FindObj('ellipsisSection').innerHTML = '"
              + TextUtility.escapeJSString(ellipsisStr) +
              "';nd();return false;\"" +
          ">" +
          "..." +
          "</a>" +
          "</span>"
          );
    }
    
    if (!Utility.isEmpty(rootFolderPathBuffer)) {
      locationBuffer.insert(0, rootFolderPathBuffer);
    }
    
    request.setAttribute(PagePathTag.NAVIGATION_FOLDER_LOCATION_KEY, locationBuffer.toString());
  }
}
